package org.leetcode.middle.leetcode394;


import java.util.LinkedList;
import java.util.Stack;

public class Solution {

    public String decodeString5(String s) {
        int n = s.length();
        Stack<String> stack = new Stack<>();
        for (int i = 0; i < n; i++) {
            char ch = s.charAt(i);
            if (ch==']'){
                StringBuilder midStr = new StringBuilder();
                while (!stack.isEmpty() && !stack.peek().equals("[")) {
                    midStr.append(stack.pop());
                }
               midStr.reverse();
                if (!stack.isEmpty()) {
                    stack.pop(); // 弹出 '['
                }
               StringBuilder repeatNum =new StringBuilder();

               while (!stack.isEmpty() && Character.isDigit(stack.peek().charAt(0))){
                   repeatNum.append(stack.pop());
               }
               repeatNum.reverse();

               int times = get(repeatNum.toString());
               StringBuilder repeatMid = new StringBuilder();
               while (times>0){
                   times--;
                   repeatMid.append(midStr);
               }
               stack.push(repeatMid.toString());

            }else {
                stack.push(Character.toString(ch));
            }
        }

        StringBuilder res = new StringBuilder();
        while (!stack.isEmpty()) {
            res.insert(0, stack.pop());
        }

        return res.toString();
    }

    private int get(String s) {
        int sum = 0;
        for (int i = 0; i < s.length(); i++) {
            sum = sum * 10 + (s.charAt(i) - '0');
        }
        return sum;
    }

    public String decodeString3(String s) {
        int n = s.length();
        Stack<String> stack = new Stack<>();

        for (int i = 0; i < n; i++) {
            char ch = s.charAt(i);
            if (ch == ']') {
                // 收集位于 `[` 前的字符串部分
                StringBuilder mid = new StringBuilder();
                while (!stack.peek().equals("[")) {
                    mid.insert(0, stack.pop());
                }
                stack.pop(); // 弹出 `[`

                // 处理多次重复的数字部分
                StringBuilder repeat = new StringBuilder();

                while (!stack.isEmpty() && Character.isDigit(stack.peek().charAt(0))) {
                        repeat.append(stack.pop());
                }

                repeat.reverse();
                // 将字符串形式的数字转换为整数
                int time = get(repeat.toString());

                // 重复 mid 中的字符串
                StringBuilder midRes = new StringBuilder();
                while (time >0) {
                    time--;
                    midRes.append(mid);
                }

                // 将结果推回栈中
                stack.push(midRes.toString());
            } else {
                // 直接将字符或字符串推入栈中
                stack.push(Character.toString(ch));
            }
        }

        // 从栈中收集最终的结果
        StringBuilder res = new StringBuilder();
        while (!stack.isEmpty()) {
            res.insert(0, stack.pop());
        }

        return res.toString();
    }

    public String decodeString2(String s){
        StringBuilder res = new StringBuilder();
        int multi=0;

        LinkedList<String> stack_res = new LinkedList<>();

        LinkedList<Integer> stack_multi = new LinkedList<>();

        for (Character c :s.toCharArray()) {
            if (c=='['){
                stack_multi.addLast(multi);
                stack_res.addLast(res.toString());

                multi=0;
                res=new StringBuilder();
            }else if (c==']'){
                StringBuilder tempRes = new StringBuilder();
                int cur_multi=stack_multi.removeLast();
                for (int i = 0; i < cur_multi; i++) {
                    tempRes.append(res);
                }
                res=new StringBuilder(stack_res.removeLast()+tempRes);

            }else if (c>='0' && c<='9'){
                multi=multi*10+Integer.parseInt(c.toString());
            }else {
                res.append(c);
            }
        }

        return res.toString();
    }
    public String decodeString(String s) {

        StringBuilder res = new StringBuilder();
        int multi = 0;
        LinkedList<Integer> stack_multi = new LinkedList<>();
        LinkedList<String> stack_res = new LinkedList<>();
        for(Character c : s.toCharArray()) {
            if(c == '[') {
                stack_multi.addLast(multi);
                stack_res.addLast(res.toString());
                multi = 0;
                res = new StringBuilder();
            }
            else if(c == ']') {
                StringBuilder tmp = new StringBuilder();
                int cur_multi = stack_multi.removeLast();
                for(int i = 0; i < cur_multi; i++) tmp.append(res);
                res = new StringBuilder(stack_res.removeLast() + tmp);
            }
            else if(c >= '0' && c <= '9') multi = multi * 10 + Integer.parseInt(c + "");
            else res.append(c);
        }
        return res.toString();

    }

    public static void main(String[] args) {
        Solution solution = new Solution();

//        String s = solution.decodeString("3[a]2[bc]");
//
//        System.out.println(s);

//        LinkedList<String> stack_res = new LinkedList<>();
//
//        stack_res.addLast("Z");
//        stack_res.addLast("H");
//        stack_res.addLast("E");
//
//        System.out.println(stack_res);

//        Character c1= 'z';
//        System.out.println(c1);
//        System.out.println(c1.toString());
    }
}
